using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using Wikey.Domain.Components;
using Wikey.Entity;
using Wikey.Utilities.Extensions;

namespace Wikey.Domain.Repository
{
    public interface IPageRepository : IQueryableRepository<Page> 
    {
        bool UniqueName(Page p);
        PagedList<Page> Paging(Pager p);
        int Save(Page page);
        Page Find(int id);
        Page Find(string url);
        List<Page> GetChildPages(int pageId);
        List<Page> SelectAll();
        IList<Page> FindByTag(string tag);
    }

    public class PageRepository : Repository, IPageRepository
    {
        public PageRepository(ISessionSource source) : base(source)
        {
            
        }

        public PageRepository(ISession session) : base(session)
        {
            
        }

        public bool UniqueName( Page page )
        {
            return !(from p in Context().Pages
                    where p.Name.Equals(page.Name)
                    select p).Any();
        }

        public IQueryable<Page> Selectable()
        {
            
            return from p in Context().Pages select p;
        }

        public List<Page> SelectAll()
        {
            
            return (from p in Context().Pages
                    orderby p.Name
                   select p ).ToList();
        }

        public IList<Page> FindByTag(string tag)
        {
            return (from p in Context().Pages where p.Tags.Contains(tag) orderby p.Name select p).ToList();
        }

        public PagedList<Page> Paging(Pager pager)
        {
            base.InfoSession();
            var baseQuery = from p in Context().Pages
                            select p;

              var dataQuery = baseQuery.Skip(pager.FirstRecord).Take(pager.RecordsPerPage);
            return new PagedList<Page>(pager, dataQuery as List<Page>, baseQuery.Count());
        }

        public List<Page> GetChildPages( int pageId )
        {
            base.InfoSession();
           var queryResult = from p in Context().Pages
                              where p.Parent.Id == pageId
                              select p;

            return queryResult.ToList();
        }

        public int Save ( Page page )
        {
            page.Name = page.Name.Trim();
            page.FriendlyName = page.Name.UrlFriendlyName();
            base.Save(page);

            return page.Id;
        }

        public Page Find( int id )
        {
            var baseQuery = from p in Context().Pages
                            where p.Id == id 
                            select p;
            // Do this automatically by Mapping
            Page page = baseQuery.FirstOrDefault();
            if( page == null )
                return null;

            page.SubPages = GetChildPages(page.Id);

            return page; 
        }

        public Page Find(string url)
        {
            if( String.IsNullOrEmpty(url))
                return new Page();

            var foundPages = from p in Context().Pages
                   where p.FriendlyName.Equals(url)
                   select p;

            Page page = foundPages.First();
            page.SubPages = GetChildPages(page.Id);

            return page; 
        }
    }
}